﻿using AppManager.Model;
using AppManager.service;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace AppManager.Component
{
    public class AppPanel : StackPanel
    {
        private AppModel App;
        private Button StartButton;
        private Button StopButton;
        private Button RestartButton;
        private Button LogButton;
        private Image Icon;

        private ProcessService Process;
        private ProcessStatus ProcessStatus;

        private void SetProcessStatus(ProcessStatus status)
        {
            this.ProcessStatus = status;
            // 改变相关按钮状态
            this.Dispatcher.Invoke(() => redefineButtonStatus());
        }

        public AppPanel(AppModel app) : base()
        {
            this.App = app;
            this.init();
            this.Process = new ProcessService(
                cmd: app.Cmd,
                args: app.Args,
                workingDirectory: app.WorkingDirectory,
                useShellExecute: app.UseShellExecute,
                stopWhenExit: app.StopWhenExit,
                env: app.Env
            );
        }

        private void init()
        {
            this.Margin = new Thickness(10, 10, 0, 0);
            var app = this.App;

            this.Icon = new Image()
            {
                Width = 64,
                Height = 64,
                ToolTip = app.Name,
            };
            var icon = app.Icon;
            if (string.IsNullOrEmpty(icon)) icon = "/static/imgs/true.jpg";
            this.Icon.Source = new BitmapImage(new Uri($"pack://siteoforigin:,,,{icon}"));

            this.StartButton = new Button() { Height = 20, Content = "启动", };
            this.StopButton = new Button() { Height = 20, Content = "停止", };
            this.RestartButton = new Button() { Height = 20, Content = "重启", };
            this.LogButton = new Button() { Height = 20, Content = "日志", };

            this.StartButton.Click += StartButton_Click;
            this.StopButton.Click += StopButton_Click;
            this.RestartButton.Click += RestartButton_Click;
            this.LogButton.Click += LogButton_Click;

            this.Children.Add(this.Icon);
            this.Children.Add(this.StartButton);
            this.Children.Add(this.StopButton);
            this.Children.Add(this.RestartButton);
            this.Children.Add(this.LogButton);

            this.SetProcessStatus(ProcessStatus.Stopped);
        }

        private void LogButton_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine($"log {this.App.Id}...");
        }

        private void RestartButton_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine($"restart {this.App.Id}...");
            this.runInNewThread(() =>
            {
                this.SetProcessStatus(ProcessStatus.Stopping);
                stopApp();
                this.SetProcessStatus(ProcessStatus.Stopped);
                this.SetProcessStatus(ProcessStatus.Starting);
                startApp();
                this.SetProcessStatus(ProcessStatus.Running);
            });
        }

        private void StopButton_Click(object sender, RoutedEventArgs e)
        {
            this.runInNewThread(() =>
            {
                this.SetProcessStatus(ProcessStatus.Stopping);
                stopApp();
                this.SetProcessStatus(ProcessStatus.Stopped);
            });
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            this.runInNewThread(() =>
            {
                this.SetProcessStatus(ProcessStatus.Starting);
                startApp();
                this.SetProcessStatus(ProcessStatus.Running);
            });
        }

        private void startApp()
        {
            Console.WriteLine($"start {this.App.Id}...");
            this.Process.Start();
        }

        private void stopApp()
        {
            Console.WriteLine($"stop {this.App.Id}...");
            this.Process.Stop();
        }

        private void runInNewThread(Action action)
        {
            Task.Run(action);
        }

        private void redefineButtonStatus()
        {
            switch (this.ProcessStatus)
            {
                case ProcessStatus.Stopped:
                    this.StopButton.IsEnabled = false;
                    this.RestartButton.IsEnabled = false;
                    this.StartButton.IsEnabled = true;
                    break;
                case ProcessStatus.Starting:
                    this.StopButton.IsEnabled = false;
                    this.RestartButton.IsEnabled = false;
                    this.StartButton.IsEnabled = false;
                    break;
                case ProcessStatus.Running:
                    this.StopButton.IsEnabled = true;
                    this.RestartButton.IsEnabled = true;
                    this.StartButton.IsEnabled = false;
                    break;
                case ProcessStatus.Stopping:
                    this.StopButton.IsEnabled = false;
                    this.RestartButton.IsEnabled = false;
                    this.StartButton.IsEnabled = false;
                    break;
                default:
                    break;
            }
        }
    }

    enum ProcessStatus
    {
        Stopped,
        Starting,
        Running,
        Stopping,
    }
}
